package com.example.mskefu.service;

import com.example.mskefu.entity.Message;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.xml.crypto.Data;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/api/websocket/{userId}")
@Component
public class WebSocketService {
    // 使用线程安全的Map存储所有连接的用户会话
    private static ConcurrentHashMap<String, WebSocketService> webSocketSet = new ConcurrentHashMap<>();

    private static MessageService messageService;
    // 当前用户的会话
    private Session session;

    // 当前用户ID
    private String userId;

    @Autowired
    public void setMessageService(MessageService service) {
        messageService = service;
    }
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {
        this.userId = userId;
        this.session = session;

        // 将当前用户的WebSocket实例存储到Map中
        webSocketSet.put(userId, this);
        System.out.println("用户 " + userId + " 已连接，当前在线人数为: " + webSocketSet.size());

        // 可以发送连接成功的消息给用户
        sendMessage("欢迎您，用户 " + userId + "！您已成功连接。");
    }

    /**
     * 收到客户端消息时调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("用户 " + userId + " 发送了消息：" + message);

        try {
            // 解析消息格式，例如: "to:目标用户ID:消息内容" 或 "broadcast:消息内容"
            if (message.startsWith("to:")) {
                // 私聊消息格式: to:目标用户ID:消息内容
                String[] parts = message.split(":", 3);
                if (parts.length == 3) {
                    String targetUserId = parts[1];
                    String content = parts[2];
                    sendToUser(targetUserId, "来自用户 " + userId + " 的私信: " + content);
                }
            } else if (message.startsWith("broadcast:")) {
                // 广播消息格式: broadcast:消息内容
                String content = message.substring(10);
                broadcastMessage("广播消息 [" + userId + "]: " + content);
            } else {
                // 检查是否是新的三段式格式: targetUserId:shopId:content
                String[] parts = message.split(":", 3);
                if (parts.length == 3) {
                    // 新的客服消息格式: targetUserId:shopId:content
                    String targetUserId = parts[0];
                    String shopId = parts[1];
                    String content = parts[2];

                    // 发送消息给目标用户
                    sendToUser(targetUserId, userId + ": " + content);

                    // 保存消息到数据库
                    saveMessageToDatabase(userId, targetUserId, content, shopId);
                } else if (parts.length == 2) {
                    // 默认处理为私聊消息，格式: 目标用户ID:消息内容
                    String targetUserId = parts[0];
                    String content = parts[1];
                    sendToUser(targetUserId, userId + ": " + content);
                }
            }
        } catch (Exception e) {
            System.err.println("处理消息时发生错误: " + e.getMessage());
            sendMessage("消息发送失败");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        // 从Map中移除当前用户
        webSocketSet.remove(userId);
        System.out.println("用户 " + userId + " 已断开连接，当前在线人数为: " + webSocketSet.size());
    }

    /**
     * 发生错误时调用的方法
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.err.println("用户 " + userId + " 发生错误: " + error.getMessage());
        error.printStackTrace();
    }
    private void saveMessageToDatabase(String senderId, String receiverId, String content,String shopId) {
        try {
            if (messageService != null) {
                Message msg = new Message();
                msg.setFszId(senderId);
                msg.setJszId(receiverId);
                msg.setText(content);
                msg.setShopId(shopId);
                msg.setTime(new Date()); // 或使用日期格式
                msg.setUrl(null);

                messageService.save(msg);
                System.out.println("消息已保存到数据库: " + content);
            }
        } catch (Exception e) {
            System.err.println("保存消息到数据库时发生错误: " + e.getMessage());
        }
    }
    /**
     * 发送消息给指定用户
     *
     * @param targetUserId 目标用户ID
     * @param message 消息内容
     */
    public void sendToUser(String targetUserId, String message) {
        try {
            // 从Map中获取目标用户的WebSocket实例
            WebSocketService targetWebSocket = webSocketSet.get(targetUserId);

            if (targetWebSocket != null) {
                // 发送消息给目标用户
                targetWebSocket.sendMessage(message);
                System.out.println("向用户 " + targetUserId + " 发送消息: " + message);
            } else {
                // 目标用户不在线
                sendMessage("用户 " + targetUserId + " 不在线");
                System.out.println("用户 " + targetUserId + " 不在线");
            }


        } catch (Exception e) {
            System.err.println("向用户 " + targetUserId + " 发送消息时发生错误: " + e.getMessage());
        }
    }

    /**
     * 广播消息给所有在线用户
     *
     * @param message 消息内容
     */
    public void broadcastMessage(String message) {
        System.out.println("开始广播消息: " + message);

        // 遍历所有在线用户并发送消息
        for (WebSocketService webSocket : webSocketSet.values()) {
            try {
                webSocket.sendMessage(message);
            } catch (Exception e) {
                System.err.println("广播消息给用户 " + webSocket.userId + " 时发生错误: " + e.getMessage());
            }
        }
    }

    /**
     * 发送消息给当前用户
     *
     * @param message 消息内容
     */
    public void sendMessage(String message) {
        try {
            // 同步发送消息，避免并发问题
            synchronized (session) {
                this.session.getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            System.err.println("向用户 " + userId + " 发送消息时发生IO错误: " + e.getMessage());
        }
    }

    /**
     * 获取当前在线用户列表
     *
     * @return 在线用户ID列表
     */
    public static String getOnlineUsers() {
        return webSocketSet.keySet().toString();
    }

    /**
     * 获取在线用户数量
     *
     * @return 在线用户数量
     */
    public static int getOnlineCount() {
        return webSocketSet.size();
    }
}
